<template>
  <CustomDialog :drag-dialog="dialogInfo">
    <el-tabs type="border-card">
      <el-tab-pane label="主内容">
        <el-form ref="form" :model="form" :rules="rules" size="mini" label-width="160px">
          <el-row :gutter="2">
            <el-col :span="8">
              <el-form-item label="编码" prop="busMainData.reportCode">
                <el-input v-model="reportCode" :disabled="!isAdd" style="width: 200px;" />
              </el-form-item>
              <el-form-item label="报表名称" prop="busMainData.reportName">
                <el-input v-model="form.busMainData.reportName" style="width: 200px;">
                  <el-button slot="append" icon="el-icon-plus" title="点击添加多语言" @click="addMultiLan" />
                </el-input>
                <multi-report-lan ref="multiReportLan" :sup_this="this" :report-lan-list="form.reportLanList" :name="form.busMainData.reportName" />
              </el-form-item>
              <el-form-item label="移动端图标" prop="busMainData.mobileIcon">
                <template slot="label">
                  移动端图标<IconHelp display-content="有值表示在移动端显示." />
                </template>
                <el-select v-model="form.busMainData.mobileIcon" size="mini" style="width: 300px;" clearable placeholder="请选择">
                  <el-option v-for="item in dicts.mobile_icon" :key="item.id" :label="item.dictName" :value="item.dictCode"/>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="显示类型" prop="busMainData.reportDisplayType">
                <el-select v-model="form.busMainData.reportDisplayType" style="width: 140px;" placeholder="报表显示类型">
                  <el-option
                    v-for="(item) in dicts.report_display_type"
                    :key="item.id"
                    :label="item.dictName"
                    :value="item.dictCode"/>
                </el-select>
                <el-select v-if="form.busMainData.reportDisplayType === 'chart'" v-model="chartDisplayType" style="width: 150px;" multiple placeholder="请选择显示图表">
                  <el-option
                    v-for="(item) in dicts.report_chart_type"
                    :key="item.id"
                    :label="item.dictName"
                    :value="item.dictCode"/>
                </el-select>
              </el-form-item>
              <el-form-item label="菜单" prop="busMainData.menuFlag">
                <el-checkbox v-model="form.busMainData.menuFlag" label="是否显示" true-label="Y" false-label="N" />
                <el-input v-if="form.busMainData.menuFlag === 'Y'" v-model="form.busMainData.reportMenuName" style="width: 200px;" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="排序" prop="busMainData.reportSort">
                <el-input-number v-model.number="form.busMainData.reportSort" :min="1" :max="999" controls-position="right" style="width: 200px;"/>
              </el-form-item>
              <el-form-item label="备注" prop="busMainData.rmk">
                <el-input v-model="form.busMainData.rmk" style="width: 200px;" />
              </el-form-item>
              <el-form-item label="权限设置" prop="busMainData.allPrivFlag">
                <el-checkbox v-model="form.busMainData.allPrivFlag" label="开放所有" true-label="Y" false-label="N" />
                <el-select v-if="form.busMainData.allPrivFlag === 'N'" v-model="form.busMainData.reportCpyList" style="width: 150px;" multiple placeholder="请选择公司">
                  <el-option
                    v-for="(item, index) in cpyList"
                    :key="item.cpyCode + index"
                    :label="item.cpyName"
                    :value="item.cpyCode"/>
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <div v-permission="['SYS_ADMIN']" class="crud-opts">
          <el-button
            class="filter-item"
            size="mini"
            type="primary"
            @click="doParseSql()">测试Sql</el-button>
          <el-button
            class="filter-item"
            size="mini"
            type="primary"
            @click="fetchField()">获取字段</el-button>
        </div>
        <div id="reportSqlEditor" class="sql-editor" />
      </el-tab-pane>
      <el-tab-pane label="报表参数">
        <el-row>
          <el-col :span="24">
            <el-table
              :data="form.reportParamList"
              stripe
              border
              style="width: 100%">
              <el-table-column prop="paramSort" label="排序" width="80px">
                <template slot-scope="scope">
                  <el-input-number v-model.number="scope.row.paramSort" :controls="false" :precision="0" :max="99" :min="1" style="width:100%" size="mini"/>
                </template>
              </el-table-column>
              <el-table-column label="参数类型" prop="paramType" width="180px">
                <template slot-scope="scope">
                  <el-select v-model="scope.row.paramType" style="width:100%" size="mini" placeholder="参数类型">
                    <el-option
                      v-for="(item) in dicts.report_param_type"
                      :key="item.id"
                      :label="item.dictName"
                      :value="item.dictCode"/>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="paramName" label="参数" width="120px">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.paramName" style="width:100%" size="mini"/>
                </template>
              </el-table-column>
              <el-table-column prop="paramDisplayName" label="显示名称" width="150px">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.paramDisplayName" style="width:100%" size="mini"/>
                </template>
              </el-table-column>
              <el-table-column prop="paramDefaultValue" label="默认值" width="100px">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.paramDefaultValue" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column prop="paramQueryFlag" label="显示" width="100px">
                <template slot-scope="scope">
                  <el-checkbox v-model="scope.row.paramQueryFlag" style="width:100%" size="mini" true-label="Y" false-label="N" />
                </template>
              </el-table-column>
              <el-table-column prop="paramWidth" label="宽度" width="100px">
                <template slot-scope="scope">
                  <el-input-number v-model.number="scope.row.paramWidth" :controls="false" :precision="0" :max="1000" :min="50" style="width:100%" size="mini"/>
                </template>
              </el-table-column>
              <el-table-column prop="dictTypeCode" label="字典类别" width="110px">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.dictTypeCode" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column prop="paramExpression" label="取值表达式">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.paramExpression" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column label="操作" width="80px">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" @click="handleParamDelete(scope.$index, scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-col>
          <el-col :span="24">
            <div class="el-table-add-row" style="width: 99.2%;" @click="addParam"><span>+ 添加</span></div>
          </el-col>
        </el-row>
      </el-tab-pane>
      <el-tab-pane label="报表字段">
        <el-row>
          <el-col :span="24">
            <el-table
              :data="form.reportFieldList"
              stripe
              border
              max-height="500px"
              style="width: 100%">
              <el-table-column prop="fieldSort" label="排序" width="80px">
                <template slot-scope="scope">
                  <el-input-number v-model.number="scope.row.fieldSort" :controls="false" :precision="0" style="width:100%" size="mini"/>
                </template>
              </el-table-column>
              <el-table-column label="类型" prop="paramType" width="150px">
                <template slot-scope="scope">
                  <el-select v-model="scope.row.fieldType" style="width:100%" size="mini" placeholder="类型">
                    <el-option
                      v-for="(item) in dicts.report_field_type"
                      :key="item.id"
                      :label="item.dictName"
                      :value="item.dictCode"/>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="fieldName" label="字段名称" width="120px">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldName" />
                </template>
              </el-table-column>
              <el-table-column prop="fieldDisplayName" label="显示名称" width="150px">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldDisplayName" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column prop="fieldWidth" label="宽度" width="100px">
                <template slot-scope="scope">
                  <el-input-number v-model.number="scope.row.fieldWidth" :controls="false" :precision="0" :max="1000" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column prop="fieldDisplayFlag" label="是否显示" width="100px">
                <template slot-scope="scope">
                  <el-checkbox v-model="scope.row.fieldDisplayFlag" true-label="Y" false-label="N" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column label="扩展属性" prop="fieldExtend">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldExtend" placeholder="json格式" style="width:100%" size="mini" />
                </template>
              </el-table-column>
              <el-table-column label="引用类型" prop="fieldHrefType">
                <template slot-scope="scope">
                  <el-select v-model="scope.row.fieldHrefType" style="width:100%" size="mini" placeholder="引用类型">
                    <el-option
                      v-for="(item) in dicts.report_href_type"
                      :key="item.id"
                      :label="item.dictName"
                      :value="item.dictCode"/>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="fieldHref" label="跳转地址" style="width:100%" size="mini">
                <template slot-scope="scope">
                  <el-input v-model="scope.row.fieldHref" />
                </template>
              </el-table-column>
              <el-table-column label="操作" width="80px">
                <template slot-scope="scope">
                  <el-button size="mini" type="danger" @click="handleFieldDelete(scope.$index, scope.row)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-col>
          <el-col :span="24">
            <div class="el-table-add-row" style="width: 99.2%;" @click="addField"><span>+ 添加</span></div>
          </el-col>
        </el-row>
      </el-tab-pane>
    </el-tabs>
    <div v-permission="['SYS_ADMIN']" v-if="form.busPageInfo.editable" slot="footer" class="modal-footer">
      <el-button type="text" @click="cancel">取消</el-button>
      <el-button :loading="loading" type="primary" @click="doSubmit">保存</el-button>
    </div>
  </CustomDialog>
</template>

<script>
import { addOrEdit, viewMainData, toAdd, toCopy, toChange, doParseSql, getReportParamList, getReportFieldList, getReportLanByReportId } from '@/api/report/reportDefine'
import * as monaco from 'monaco-editor'
import { getAllCpy } from '@/api/system/cpy'
import multiReportLan from './multiReportLan'

export default {
  components: { multiReportLan },
  dictTypes: ['mobile_icon', 'report_param_type', 'report_query_mode', 'report_href_type', 'report_display_type', 'report_field_type', 'report_chart_type'],
  props: {
    sup_this: {
      type: Object,
      required: true
    }
  },
  data() {
    return {
      isAdd: false,
      loading: false,
      style: 'width: 184px',
      dialogInfo: {
        name: 'reportDefineFormDialog',
        title: '报表定义维护',
        fullScreen: true
      },
      cpyList: [],
      cpyCodes: [],
      form: {
        busMainData: {
          id: '',
          enableFlag: 'Y',
          reportCpyList: []
        },
        reportLanList: [],
        reportParamList: [],
        reportFieldList: [],
        busPageInfo: {
        }
      },
      rules: {
        'busMainData.reportCode': [
          { required: true, message: '请输入编号', trigger: 'blur' },
          { min: 3, max: 50, message: '长度在 3 到 50 个字符', trigger: 'blur' }
        ],
        'busMainData.reportName': [
          { required: true, message: '请输入编号', trigger: 'blur' },
          { min: 2, max: 100, message: '长度在 3 到 100 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  computed: {
    reportCode: {
      get: function() {
        return this.form.busMainData.reportCode
      },
      set: function(val) {
        this.form.busMainData.reportCode = val.toUpperCase()
      }
    },
    chartDisplayType: {
      get: function() {
        if (this.form.busMainData.chartDisplayType) {
          return JSON.parse(this.form.busMainData.chartDisplayType)
        }
        return []
      },
      set: function(val) {
        this.form.busMainData.chartDisplayType = JSON.stringify(val)
      }
    }
  },
  mounted() {
    getAllCpy().then(res => {
      this.cpyList = res.data
    })
  },
  methods: {
    cancel() {
      this.resetForm()
    },
    initDataOfBefore() {
    },
    displayDialog() {
      const { name } = this.dialogInfo
      this.$nextTick(() => {
        this.$modal.show(name)
      })
    },
    hiddenDialog() {
      const { name } = this.dialogInfo
      this.$nextTick(() => {
        this.$modal.hide(name)
      })
    },
    processOtherData(mainId) {
      setTimeout(() => {
        this.setSqlEditorValue()
      }, 1000)
      if (mainId) {
        getReportLanByReportId(mainId).then(res => {
          this.form.reportLanList = res.data
        })
        getReportParamList(mainId).then(res => {
          this.form.reportParamList = res.data
        })
        getReportFieldList(mainId).then(res => {
          this.form.reportFieldList = res.data
        })
      }
    },
    addData() {
      this.isAdd = true
      const data = { paramBean: {}}
      toAdd(data).then(res => {
        this.displayDialog()
        this.form = res.data
        this.processOtherData()
      }).catch(err => {
        console.log(err)
      })
    },
    copyData(mainId) {
      this.isAdd = true
      const data = { paramBean: { id: mainId }}
      toCopy(data).then(res => {
        this.displayDialog()
        this.form = res.data
        this.processOtherData(mainId)
      }).catch(err => {
        console.log(err)
      })
    },
    changeData(busId) {
      const data = { paramBean: { id: busId }}
      toChange(data).then(res => {
        this.displayDialog()
        this.form = res.data
        this.processOtherData(this.form.busMainData.oldMainId)
      }).catch(err => {
        console.log(err)
      })
    },
    addParam() {
      const len = this.form.reportParamList.length + 1
      const addRow = { paramType: 'string', paramQueryFlag: 'Y', paramQueryMode: 'single', paramWidth: 150, paramSort: len }
      this.form.reportParamList.push(addRow)
    },
    addField() {
      const len = this.form.reportFieldList.length + 1
      const addRow = { fieldType: 'string', fieldSort: len, fieldDisplayFlag: 'Y', fieldWidth: 150 }
      this.form.reportFieldList.push(addRow)
    },
    handleParamDelete(index, row) {
      this.form.reportParamList.splice(index, 1)
    },
    handleFieldDelete(index, row) {
      this.form.reportFieldList.splice(index, 1)
    },
    viewMainData(id) {
      this.isAdd = false
      const data = { paramBean: { id: id }}
      viewMainData(data).then(res => {
        this.displayDialog()
        this.form = res.data
        this.processOtherData(id)
      })
    },
    doSubmit() {
      this.$refs['form'].validate((valid) => {
        if (valid) {
          const sqlStr = this.sqlEditor.getValue()
          this.form.busMainData.reportSql = sqlStr
          if (this.form.busMainData.allPrivFlag === 'Y') {
            const tmpCpyArr = []
            this.cpyList.forEach(tmpcpy => {
              tmpCpyArr.push(tmpcpy.cpyCode)
            })
            this.form.busMainData.reportCpyList = tmpCpyArr
          }
          this.loading = true
          if (this.isAdd) {
            this.doAdd()
          } else {
            this.doEdit()
          }
        }
      })
    },
    doAdd() {
      addOrEdit(this.form).then(res => {
        this.resetForm()
        this.loading = false
        this.sup_this.init()
      }).catch(err => {
        this.loading = false
        console.log(err)
      })
    },
    doEdit() {
      addOrEdit(this.form).then(res => {
        this.resetForm()
        this.loading = false
        this.sup_this.init()
      }).catch(err => {
        this.loading = false
        console.log(err)
      })
    },
    resetForm() {
      this.hiddenDialog()
      this.$refs['form'].resetFields()
    },
    setSqlEditorValue() {
      const id = 'reportSqlEditor'
      const formatSql = this.form.busMainData.reportSql // beautifier.html(this.form.busMainData.reportSql, beautifierConf.html)
      this.sqlEditor = monaco.editor.create(document.getElementById(id), {
        value: formatSql,
        theme: 'vs-dark',
        language: 'sql',
        automaticLayout: true
      })
    },
    processField(data) {
      if (!data) {
        this.$notify({
          title: '返回无结果，请确保sql执行有返回记录!',
          type: 'warning',
          duration: 2000
        })
        return
      }
      const tmpFieldList = []
      const existData = {}
      this.form.reportFieldList.forEach(tmpvo => {
        existData[tmpvo.fieldName] = tmpvo
      })
      let i = 1
      for (const fieldName in data) {
        const existvo = existData[fieldName]
        if (!existvo) {
          tmpFieldList.push({ fieldSort: i, fieldName: fieldName, fieldDisplayName: fieldName, fieldDisplayFlag: 'Y', fieldType: 'string' })
        } else {
          tmpFieldList.push(existvo)
        }
        i++
      }
      this.form.reportFieldList = tmpFieldList
    },
    doParseSql(autoFetchField) {
      const sqlStr = this.sqlEditor.getValue()
      this.form.busMainData.reportSql = sqlStr
      doParseSql(this.form).then(res => {
        if (autoFetchField) {
          this.processField(res.data)
        }
      })
    },
    fetchField() {
      this.doParseSql(true)
    },
    addMultiLan() {
      // 增加多语言
      const _this = this.$refs.multiReportLan
      _this.dialog = true
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
  ::v-deep .el-input-number .el-input__inner {
    text-align: left;
  }
  .sql-editor{
    height: calc(100vh - 350px);
  }
</style>
